package cn.me.gaoji;

/**
 * @author jia
 * @date 2021/2/23
 */
//生产者消费者模型-->利用 缓冲区解决：管程法
//生产者，消费者，产品，缓冲区
    //不能正常运行https://www.bilibili.com/video/BV1V4411p7EF?p=25&spm_id_from=pageDriver
public class TestPC {
    public static void main(String[] args) {
        Chicken.SynContainer container = new Chicken.SynContainer();
        new Productor(container).start();
        new Consumer(container).start();
    }
}

//生产者
class Productor extends Thread {
    Chicken.SynContainer container;

    public Productor(Chicken.SynContainer container) {
        this.container = container;
    }

    //生产

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("生产了" + i + "只鸡");
            container.push(new Chicken(1));
        }
    }
}

//消费者
class Consumer extends Thread {
    Chicken.SynContainer container;

    public Consumer(Chicken.SynContainer container) {
        this.container = container;
    }

    //消费
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("消费了--》" + container.pop().id + "只鸡");
        }
    }
}

class Chicken {

    int id;//产品编号

    public Chicken(int id) {
        this.id = id;
    }


    //缓冲区
    static class SynContainer {

        //需要一个容器大小
        Chicken[] chickens = new Chicken[10];
        //容器计数器；
        int count = 0;

        //生产者放入产品
        public synchronized void push(Chicken chicken) {
            //如果容器满了，就需要消费等待
            if (count == chickens.length) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //如果没有满，就需要丢入产品
            chickens[count] = chicken;
            count++;
            //通知消费者消费
            this.notifyAll();
        }

        //消费者产品
        public synchronized Chicken pop() {
            //判断
            if (count == 0) {
                //等待生产者生产，消费者等待
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //如果可以消费
            count--;
            Chicken chicken = chickens[count];

            //没了，通知生产者生产
            this.notifyAll();
            return chicken;
        }

    }
}
